#include "ssmt.h"
#include "scripting/script_manager.h"
//#include "entitysystem/entitysystem.h"
#include "container/indexed_array.h"

#include "memory\memory_arena.h"
#include "memory\boundschecking.h"
#include "memory\memorytracking.h"
#include "memory\linearallocator.h"
#include "memory\heaparena.h"



#include <algorithm>
#include "serialize/iserializer.h"

#ifdef _DEBUG
	#define _CRTDBG_MAP_ALLOC
	#include <stdlib.h>
	#include <crtdbg.h>
#endif

typedef ssmt::MemoryArena<ssmt::allocator::LinearAllocator,ssmt::boundschecking::SimpleBoundsChecking,ssmt::tracking::NoMemoryTracking> LinearArena;

class Test
{
public:
	Test() 
	{
		valuea = 10;
		valueb = 212;
		baba = 219;
		std::memset(t,0x11,133);
	}

	~Test()
	{

	}

	void setValue(int v)
	{
		valueb = v;
	}

private:
	int valuea;
	int valueb;
	long baba;
	char t[133];

};


int main(int argc, char* argv[])
{

#ifdef _DEBUG
	_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

	std::cout << ":::::::::::::::::::::::::\n:: SSMT \n:: Author: Nikolaus Poettler\n:::::::::::::::::::::::::\n" << std::endl;
	std::cout << " ~ Initialising Systems...\n";
	ssmt::ScriptManager sm;
	int32_t i = sm.load("Win32TestDll.dll");
	sm.initializeScriptAt(i);
	
	ssmt::HeapArea heapArea(2048);
	
	LinearArena linearArena(heapArea);
	Test* t = SSMT_NEW(Test,linearArena)();
	t;
	SSMT_DELETE(t,linearArena);
	//int test = 32767;
	//ssmt::serializer::InstanceToMemoryS s;
   //
	//std::vector<char> memory;
	//s.UseMemory(&memory);
	//s.serialize("test",&test,5);
	//
	//for(unsigned int i = 0;i<memory.size();i++)
	//{
	//	std::cout << memory.at(i) << std::endl;
	//}
	//
	//ssmt::serializer::MemoryToInstanceS sMtI;
	//sMtI.UseMemory(&memory);
	//int readTest;
	//sMtI.serialize("test",&readTest,10);
	//
	//std::cout << readTest << std::endl;
	//

	std::vector<char> memory;

	int data = 55555;

	const unsigned char *ptr = static_cast<const unsigned char*>(static_cast<void*>(&data));
	memory.insert(memory.end(), ptr, ptr + sizeof(int));

	float secondData = 0.01f;

	const unsigned char *ptr2 = static_cast<const unsigned char*>(static_cast<void*>(&secondData));
	memory.insert(memory.end(), ptr2, ptr2 + sizeof(float));

	int newData;
	memcpy(&newData,&memory[0],sizeof(int));

	size_t offset = sizeof(int);

	std::cout << newData << std::endl;

	float newSecondData;
	memcpy(&newSecondData,&memory[offset],sizeof(float));

	std::cout << newSecondData << std::endl;

	char* thirdData = "Hallo";
	const unsigned char *ptr3 = static_cast<const unsigned char*>(static_cast<void*>(thirdData));
	memory.insert(memory.end(), ptr3, ptr3 + sizeof(char)*strlen(thirdData));

	offset += sizeof(int);//sizeof(char)*strlen(thirdData+1);

	//Ensure enough space..
	char* newThirdData;
	newThirdData = static_cast<char*>(alloca(sizeof(char)*strlen(thirdData)));
	
	memcpy(newThirdData,&memory[offset],sizeof(char)*strlen(thirdData));
	newThirdData[5] = '\0';
	std::cout << newThirdData << std::endl;

	//template <size_t Size>
	//class bla{
	//
	// char t[Size];
	//
	// char* getStart()const{
	//  return t; 
	// }
	// char* getEnd() const{
	//  return t+S;
	// }
	//};
	//
	//bla<1829> z();
}
